<?php

/**
 * *基于*原有逻辑是使用网点编号匹配二段码,
 * 使用一段码是由于二段码的值取决于一段码(非固定)只是用于确定网点编号进而获取二段吗
 * 如果二段码是稳定的,可以忽略一段码的获取了
 */
abstract class StoCodeTableBuilder
{

    const CLASS_TPL = 'Sto%sTableBuilder';
    const CODE_TYPE = [
      'FirstCode',
      'SecondCode'
    ];

    const FILE_CONTENT_PREFIX = <<<ARRAY
<?php\r\n
return\t
ARRAY;

    protected static $requiredFields = [];

    protected $sourceFilePath;
    protected $fileSeparator;
    /**
     * 表里所有的数据
     * @var array
     */
    protected $codeArray;

    /**
     * @var array
     */
    protected $codeColumns;

    /**
     * columns count
     * @var int
     */
    protected $columnLength;

    /**
     * @var array
     */
    protected $lastFormattedRow;

    /**
     * @var array
     */
    protected $lastFormattedRowInfo;


    /**
     * StoSecondCodeTableBuilder constructor.
     * @param string $filePath
     * @param string $fileSeparator
     */
    public function __construct(string $filePath, string $fileSeparator = ',')
    {
        if (!file_exists($filePath) || !is_readable($filePath)) {
            die(sprintf('file: %s not exists or unreadable', $filePath));
        }
        $this->sourceFilePath = $filePath;
        $fileSeparator and $this->fileSeparator = $fileSeparator;
    }

    public function run()
    {
        $this->init();
        $this->build();
        $this->toFile();
    }

    protected function findInfoPosition()
    {

    }

    /**
     * @param array $data
     * @return bool
     */
    protected function checkRequiredField(array $data) : bool
    {
        foreach (static::$requiredFields as $field => $desc) {
            if(!isset($data[$field]) || !trim($data[$field])){
                echo 'missing required params:',json_encode($data, JSON_UNESCAPED_UNICODE),PHP_EOL;
                return false;
            }
        }
        return true;
    }

    /**
     * @return mixed
     */
    abstract protected function build();

    /**
     * init
     */
    abstract protected function init();

    /**
     * file to array
     * @return array
     */
    protected function toArray(): array
    {
        if ($this->codeArray === null) {
            $fileHandler = fopen($this->sourceFilePath, 'rb');
            $arr = [];
            while (!feof($fileHandler)) {
                $line = fgets($fileHandler);
                $arr[] = explode($this->fileSeparator, $line);
            }
            fclose($fileHandler);
            $this->codeColumns = array_map('trim', array_shift($arr));
            $this->columnLength = count($this->codeColumns);
            $this->codeArray = $arr;
        }
        return $this->codeArray;
    }

    /**
     * @return array
     */
    abstract protected function toFile(): array;

    /**
     * @param array $data
     */
    protected static function printErrorInfo(array $data, string $msg = 'error happened')
    {
        echo $msg,json_encode($data, JSON_UNESCAPED_UNICODE),PHP_EOL;
    }

}
